using Lichtspiel.Math;
using OpenTK.Graphics.OpenGL;

namespace Lichtspiel.Display
{
    public class GraphicsCore
    {
        private Color clearColor;
        private Game game;

        internal GraphicsCore(Game game) {
            this.game = game;
            ClearColor = new Color(0.97f, 0.95f, 0.9f);
        }

        public Color ClearColor {
            set {
                clearColor = value;
                GL.ClearColor(clearColor.R, clearColor.G, clearColor.B, clearColor.A);
            }

            get { return clearColor; }
        }

        internal void Initialize() {
            var viewPort = new int[4];

            GL.GetInteger(GetPName.Viewport, viewPort);
            //GL.Viewport(0, 0, viewPort[0] + viewPort[2], viewPort[1] + viewPort[3]);
            GL.MatrixMode(MatrixMode.Projection);
            GL.PushMatrix();
            GL.LoadIdentity();

            GL.Ortho(viewPort[0], viewPort[0] + viewPort[2], viewPort[1] + viewPort[3], viewPort[1], -1, 1);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.PushMatrix();

            ResetTransforms();

            GL.PushAttrib(AttribMask.DepthBufferBit);
            GL.Disable(EnableCap.DepthTest);

            GL.Enable(EnableCap.Texture2D);
            GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
        }

        internal void Resize(int windowW, int windowH) {
            GL.Viewport(0, 0, windowW, windowH);
//            GL.MatrixMode(MatrixMode.Projection);
//            GL.PushMatrix();
//            GL.LoadIdentity();
//
//            GL.Ortho(0, windowW, windowH, 0, -1, 1);
//            GL.MatrixMode(MatrixMode.Modelview);
        }

        /// <summary>
        /// Clears the background.
        /// </summary>
        public void Clear() {
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
        }

        public void EnableScissoring(Rectangle rect) {
            EnableScissoring(rect.X, rect.Y, rect.Width, rect.Height);
        }

        public void EnableScissoring(int x, int y, int width, int height) {
            GL.Enable(EnableCap.ScissorTest);
            int convY = (this.game.Height - y) - height;
            GL.Scissor(x, convY, width, height); // coords converted
        }

        public void DisableScissoring() {
            GL.Disable(EnableCap.ScissorTest);
        }

        /// <summary>
        /// Translates the drawing matrix.
        /// </summary>
        /// <param name="x">X offset.</param>
        /// <param name="y">Y offset.</param>
        public void Translate(float x, float y) {
            GLHelper.Translate(x, y);
        }

        /// <summary>
        /// Translates the drawing Matrix.
        /// </summary>
        public void Translate(Vector2 offset) {
            Translate(offset.X, offset.Y);
        }

        /// <summary>
        /// Rotates the drawing Matrix.
        /// </summary>
        public void Rotate(float x, float y, float degrees) {
            GLHelper.Rotate(x, y, degrees);
        }

        /// <summary>
        /// Rotates the drawing Matrix.
        /// </summary>
        public void Rotate(Vector2 origin, float degrees) {
            Rotate(origin.X, origin.Y, degrees);
        }


        public void Scale(float x, float y, float scaleX, float scaleY) {
            GLHelper.Scale(x,y,scaleX,scaleY);
        }

        /// <summary>
        /// Resets all transforms of the drawing Matrix.
        /// </summary>
        public void ResetTransforms() {
            GLHelper.ResetTransforms();
        }
    }
}